﻿Imports System.Data.SqlClient

Public Class DataBase


  ''' <summary>
  '''флаг доступности БД
  ''' </summary>
  Public Shared FldbExist As Boolean = False

  ''' <summary>
  ''' строка подключения к БД
  ''' </summary>
  Public Shared ConString As String

  ''' <summary>
  ''' Подключение к БД
  ''' </summary>
  Private Shared ConnSql As SqlConnection = Nothing

  ''' <summary>
  ''' Инициализация строки подключения к БД
  ''' </summary>
  Public Sub InitDB()

    'загружаем параметры конфигурации
    If Not cfg.flLoadConfig Then
      cfg.ReadCfg()
    End If

    'параметры подключения БД
    ConString = "Data Source=" + ServerSQL.DataSource + ";database=" + ServerSQL.database + ";User Id=" + ServerSQL.uid + ";Password=" + ServerSQL.pwd + ";"

    'определение строки подключения к БД
    ConnSql = New SqlConnection(ConString)

  End Sub


  ''' <summary>
  ''' Возвращает коллекцию строк по запросу
  ''' </summary>
  ''' <param name="SqlStr">SQL запрос</param>
  ''' <returns>Возврат коллекции строк (в типе DataRowCollection)</returns>
  Public Function GetFields(ByVal SqlStr As String) As DataRowCollection

    Dim DRC As DataRowCollection = Nothing

    Using conn As New SqlConnection(ConString)

      conn.Open()

      Using cmd As New SqlCommand(SqlStr, conn)
        Try
          Dim rdr As SqlDataReader = Nothing
          rdr = cmd.ExecuteReader()
          If rdr IsNot Nothing Then
            'загружаем датасэт
            Dim ds As New DataSet()
            ds.Load(rdr, LoadOption.Upsert, rdr.GetSchemaTable().TableName)
            DRC = ds.Tables(0).Rows
            rdr.Close()
          End If
        Catch ex As Exception
          UI.MsgErr("При выполнении запроса к БД возникла ошибка:", ex)
        End Try
      End Using

      conn.Close()

    End Using

    Return DRC

  End Function


  ''' <summary>
  ''' Обновление записей
  ''' </summary>
  ''' <param name="DataSet">Коллекция ключей и значений (ключ - наименование поля)</param>
  ''' <param name="TableName">Наименование таблицы</param>
  ''' <param name="WhereValue">Условие (указывается без ключего слова WHERE)</param>
  Public Function SetFields(ByVal DataSet As Dictionary(Of String, String), ByVal TableName As String, ByVal WhereValue As String)

    Dim SqlStr As String = String.Format("UPDATE {0} SET ", TableName)
    Dim SqlNameParColumns As String = ""

    Dim conn As New SqlConnection(ConString)
    Dim cmd As SqlCommand = conn.CreateCommand()

    'создание части SQL запроса по наименованиям полей с использованием параметров
    For Each kvp As KeyValuePair(Of String, String) In DataSet

      If SqlNameParColumns <> "" Then
        SqlNameParColumns += ", "
      End If

      SqlNameParColumns += String.Format("{0} = {1}", kvp.Key, "@" + kvp.Key)

      cmd.Parameters.AddWithValue("@" + kvp.Key, SetQuotes(kvp.Value).ToString())

    Next

    SqlStr += SqlNameParColumns

    'условие
    If WhereValue <> "" Then SqlStr += String.Format(" WHERE {0}", WhereValue)


    'выполнение SQL конструкции
    Try

      conn.Open()

      cmd.CommandText = SqlStr
      cmd.ExecuteNonQuery()
      cmd.Parameters.Clear()

    Catch ex As Exception
      If conn.State = ConnectionState.Open Then conn.Close()
      UI.MsgErr("Во время изменения записи в БД возникла ошибка:", ex)
      Return False
    Finally

      conn.Close()
    End Try

    Return True

  End Function


  ''' <summary>
  ''' Добавление новой записи в указанную таблицу
  ''' </summary>
  ''' <param name="DataSet">Коллекция ключей и значений (ключ - наименование поля)</param>
  ''' <param name="TableName">Наименование таблицы</param>
  Public Function InsertRow(ByVal DataSet As Dictionary(Of String, String), ByVal TableName As String) As Boolean

    Dim SqlStr As String = String.Format("INSERT INTO {0}", TableName)
    Dim SqlNameColumns As String = ""
    Dim SqlParValues As String = ""

    Dim conn As New SqlConnection(ConString)
    Dim cmd As SqlCommand = conn.CreateCommand()

    'создание части SQL запроса по наименованиям полей с использованием параметров
    For Each kvp As KeyValuePair(Of String, String) In DataSet

      If SqlNameColumns <> "" Then
        SqlNameColumns += ", "
        SqlParValues += ", "
      End If

      SqlNameColumns += kvp.Key
      SqlParValues += "@" + kvp.Key
      cmd.Parameters.AddWithValue("@" + kvp.Key, SetQuotes(kvp.Value).ToString())

    Next

    If SqlNameColumns = "" Then
      Return False
    Else
      SqlStr += String.Format(" ({0}) VALUES ({1})", SqlNameColumns, SqlParValues)
    End If

    'выполнение SQL конструкции
    Try

      conn.Open()

      cmd.CommandText = SqlStr
      cmd.ExecuteNonQuery()
      cmd.Parameters.Clear()

    Catch ex As Exception
      If conn.State = ConnectionState.Open Then conn.Close()
      UI.MsgErr("Во время создании записи в БД возникла ошибка:", ex)
      Return False
    Finally

      conn.Close()
    End Try

    Return True


  End Function



  ''' <summary>
  ''' Добавление новой записи с двоичным полем в указанную таблицу
  ''' </summary>
  ''' <param name="DataSet">Коллекция ключей и значений (ключ - наименование поля)</param>
  ''' <param name="TableName">Наименование таблицы</param>
  Public Function InsertByteRow(ByVal DataSet As Dictionary(Of String, Object), ByVal TableName As String) As Boolean

    Dim SqlStr As String = String.Format("INSERT INTO {0}", TableName)
    Dim SqlNameColumns As String = ""
    Dim SqlParValues As String = ""

    Dim conn As New SqlConnection(ConString)
    Dim cmd As SqlCommand = conn.CreateCommand()

    'создание части SQL запроса по наименованиям полей с использованием параметров
    For Each kvp As KeyValuePair(Of String, Object) In DataSet

      If SqlNameColumns <> "" Then
        SqlNameColumns += ", "
        SqlParValues += ", "
      End If

      SqlNameColumns += kvp.Key
      SqlParValues += "@" + kvp.Key

      If TypeOf kvp.Value Is String Then
        cmd.Parameters.AddWithValue("@" + kvp.Key, SetQuotes(kvp.Value).ToString())
      Else
        cmd.Parameters.AddWithValue("@" + kvp.Key, kvp.Value)
      End If

    Next

    If SqlNameColumns = "" Then
      Return False
    Else

      SqlStr += String.Format(" ({0}) VALUES ({1})", SqlNameColumns, SqlParValues)

    End If

    MsgBox(SqlStr)

    'выполнение SQL конструкции
    Try

      conn.Open()

      cmd.CommandText = SqlStr
      cmd.ExecuteNonQuery()
      cmd.Parameters.Clear()

    Catch ex As Exception
      If conn.State = ConnectionState.Open Then conn.Close()
      UI.MsgErr("Во время создании записи в БД возникла ошибка:", ex)
      Return False
    Finally

      conn.Close()
    End Try

    Return True

  End Function



  ''' <summary>
  ''' Удаление записи из указанной таблицы и условием
  ''' </summary>
  ''' <param name="TableName">Наименование таблицы</param>
  ''' <param name="WhereValue">Условие (указывается без ключего слова WHERE)</param>
  Public Sub DeleteRow(ByVal TableName As String, ByVal WhereValue As String)
    Dim SqlStr As String = Convert.ToString("DELETE FROM ") & TableName
    If WhereValue.Length > 0 Then
      SqlStr += Convert.ToString(" WHERE ") & WhereValue
    End If

    Using conn As New SqlConnection(ConString)

      conn.Open()

      Using cmd As New SqlCommand(SqlStr, conn)
        Try
          cmd.ExecuteNonQuery()
        Catch ex As Exception
          Console.WriteLine(ex.Message)
        End Try
      End Using

      conn.Close()
    End Using
  End Sub


  ''' <summary>
  ''' Экранируем кавычки в SQL запросе
  ''' </summary>
  ''' <param name="SqlStr">Sql запрос</param>
  ''' <returns>Sql запрос с экранированными кавычками</returns>
  Public Function SetQuotes(ByVal SqlStr As String) As String
    SqlStr = System.Text.RegularExpressions.Regex.Replace(SqlStr, "[']", Chr(34).ToString())
    Return SqlStr
  End Function


End Class
